package com.codi.bus.core.service.impl;

import com.codi.base.util.DateUtil;
import com.codi.base.util.DateUtils;
import com.codi.base.util.EqualsUtil;
import com.codi.base.util.MD5;
import com.codi.bus.constant.FundConst;
import com.codi.bus.constant.GlobalConstant;
import com.codi.bus.core.dao.PortfolioDividentDao;
import com.codi.bus.core.fund.FundErrorConst;
import com.codi.bus.core.fund.dao.FundDividendChangeDao;
import com.codi.bus.core.fund.domain.FundDividendChange;
import com.codi.bus.core.fund.dto.FundDividendChangeQueryDto;
import com.codi.bus.core.fund.enums.DividendAutoBuyEnum;
import com.codi.bus.core.fund.enums.FundDividendChangeStatusEnum;
import com.codi.bus.core.fund.service.FundDividendChangeService;
import com.codi.bus.core.resultModel.AssetsResult;
import com.codi.bus.core.resultModel.ShareListResult;
import com.codi.bus.core.service.FundDetailService;
import com.codi.bus.core.service.WorkingDateService;
import com.codi.bus.core.service.model.ProtfolioDividentModel;
import com.codi.bus.core.service.model.ShareModel;
import com.codi.bus.core.service.util.HundsunUtils;
import com.codi.bus.core.service.util.ModelPopulateUtils;
import com.codi.fcloud.ufx.constant.HsConst;
import com.codi.fundData.domain.FundDetail;
import com.codi.message.util.MessageUtil;
import com.codi.trade.dto.HsDividendMethodTradeRequestDto;
import com.codi.trade.dto.HsShareQueryDto;
import com.codi.trade.response.HsDividendMethodTradeResponse;
import com.codi.trade.service.HsDividendMethodTradeService;
import com.codi.trade.service.ShareQueryService;
import com.github.pagehelper.PageHelper;
import com.google.common.base.Strings;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Author: zengxl
 * @Description:
 * @Date: 2018/4/16 13:41
 */
@Service
@Slf4j
public class PortfolioDividentServie {
    @Autowired
    private PortfolioDividentDao portfolioDividentDao;
    @Resource(name = "shareQueryService")
    private ShareQueryService shareQueryService;
    @Autowired
    private FundDetailService fundDetailService;
    @Autowired
    private HsDividendMethodTradeService hsDividendMethodTradeService;
    @Autowired
    private FundDividendChangeDao fundDividendChangeDao;
    @Autowired
    private WorkingDateService workingDateService;

    /**
     * 初始化存量用户购买过的组合基金，修改其分红方式为：红利再投资，执行一便即可
     */
    public void init(){
        List<ProtfolioDividentModel> objectList = portfolioDividentDao.getAllClientIds();
        exec(objectList);
    }

    /**
     * 定时任务执行服务，自动设置用户购买的组合基金的分红方式为：红利再投资
     */
    public void dividentTypeQuery(){
        Calendar now = Calendar.getInstance();
        String format = "yyyy-MM-dd HH:mm:ss";
        String edDate = DateUtils.getFormatedDate(now.getTime(),format);
        now.add(Calendar.DAY_OF_MONTH,-14);
        String bgDate =DateUtils.getFormatedDate(now.getTime(),format);
        List<ProtfolioDividentModel> objectList = portfolioDividentDao.getHasPortfolioTradeClientIds(bgDate,edDate);
        exec(objectList);
    }
    private void exec(List<ProtfolioDividentModel> objectList){
        if(objectList != null && objectList.size() > 0){
            for(ProtfolioDividentModel tt:objectList){
                String clientId = tt.getClientId();
                long userId = tt.getUserId();

                HsShareQueryDto hsShareQueryDto = HsShareQueryDto.builder()
                    .request_num(GlobalConstant.MAX_REQUEST_NUM)
                    .reqry_recordsum_flag("1")
                    .qry_beginrownum(1)
                    .sort_direction("1")
                    .client_id(clientId)
                    .build();
                Map<String, Object> map = shareQueryService.query(hsShareQueryDto);
                List<Map<String, Object>> list = new ArrayList<>();
                AssetsResult result = new AssetsResult();
                HundsunUtils.ConvertToList(map, list, result);
                if (!result.getSuccess()) {
                    continue;
                }
                ShareListResult shareListResult = new ShareListResult();
                List<ShareModel> shares = ModelPopulateUtils.populateShare(list, null, shareListResult);
                for(ShareModel model:shares){
                    //0-红利再投资，1-现金红利
                    String autoBuy = model.getAutoBuy();
                    String tradeAcc = model.getTradeAccount();

                    if(tradeAcc != null && tradeAcc.startsWith("ZH") && (autoBuy == null || !DividendAutoBuyEnum.REINVESTMENT.getKey().equals(autoBuy))){
                        FundDetail fundDetail = fundDetailService.getFundDetail(model.getFundCode());
                        if (fundDetail == null) {
                            log.warn("基金编码不存在{}", model.getFundCode());
                            continue;
                        }
                        // 修改分红方式
                        if (EqualsUtil.equals(FundConst.FUND_TYPE_CODE_CURRENCY, fundDetail.getFundTypeCode().intValue())) {
                            log.info("货币基金无需修改分红方式");
                            continue;
                        }
                        String taAcco = model.getTaAccount();
                        if (taAcco != null && taAcco.startsWith("*")) {
                            taAcco = taAcco.substring(1);
                        }
                        //change once
                        final String taAccos = taAcco;
                        Long changeCount = PageHelper.count(() -> {
                            FundDividendChangeQueryDto record = FundDividendChangeQueryDto.builder()
                                .userId(userId)
                                .tradeAcco(tradeAcc)
                                .taAcco(taAccos)
                                .fundCode(model.getFundCode())
                                // .bizType(dto.getBizType())
                                .createDate(new Date())
                                .createDateFormat("%Y%m%d")
                                .build();
                            fundDividendChangeDao.select(record);
                        });

                        if (changeCount > 0) {
                            log.warn("今日修改过分红方式", model.getFundCode());
                            continue;
                        }


                        // check applying date
                        Date workingDay = workingDateService.getWorkingDay(new Date());

                        if (workingDay != null) {
                            Long applyingCount = PageHelper.count(() -> {
                                FundDividendChangeQueryDto record = FundDividendChangeQueryDto.builder()
                                    .userId(userId)
                                    .tradeAcco(tradeAcc)
                                    .taAcco(taAccos)
                                    .fundCode(model.getFundCode())
                                    //.bizType(dto.getBizType())
                                    .applyDate(workingDay)
                                    .build();
                                fundDividendChangeDao.select(record);
                            });

                            if (applyingCount > 0) {
                                log.warn("今日分红方式修改申请已经提交，等待基金公司确认", model.getFundCode());
                                continue;
                            }
                        }

                        HsDividendMethodTradeRequestDto changeDto = HsDividendMethodTradeRequestDto.builder()
                            .ta_acco(taAcco)
                            .trade_acco(tradeAcc)
                            .password(HsConst.NOPASSWORD)
                            .fund_code(model.getFundCode())
                            .share_type(model.getShareType())
                            .auto_buy(DividendAutoBuyEnum.REINVESTMENT.getKey())
                            .build();

                        HsDividendMethodTradeResponse response = hsDividendMethodTradeService.change(changeDto);
                        if (response.getSuccess()) {
                            Date applyDate = null;
                            if (!Strings.isNullOrEmpty(response.getApply_date())) {
                                applyDate = DateUtil.parse(response.getApply_date(), "yyyyMMdd");
                            }
                            FundDividendChange record = FundDividendChange.builder()
                                .userId(userId)
                                .tradeAcco(tradeAcc)
                                .taAcco(taAcco)
                                .fundCode(model.getFundCode())
                                .shareType(model.getShareType())
                                //.bizType(dto.getBizType())
                                .autoBuy(DividendAutoBuyEnum.REINVESTMENT.getKey())
                                .allotNo(response.getAllot_no())
                                .status(FundDividendChangeStatusEnum.APPLY_SUC.getKey())
                                .createDate(new Date())
                                .applyDate(applyDate)
                                .build();

                            fundDividendChangeDao.insertSelective(record);
                        }else {
                            log.error("修改失败");
                        }

                    }
                }


            }

        }
    }

}
